<template>
  <div class="chart-container">
    <div class="chart-header">
      <h3>销售季节性分析</h3>
      <div class="legend-container">
        <div v-for="(item, index) in legendItems" :key="index" class="legend-item">
          <span class="legend-color" :style="{ backgroundColor: item.color }"></span>
          <span class="legend-text">{{ item.text }}</span>
        </div>
      </div>
    </div>
    
    <div class="chart-content" :class="{ 'is-loading': loading }">
      <div ref="chartRef" class="echarts-wrapper"></div>
      <div v-if="loading" class="loading-overlay">
        <el-skeleton animated :rows="5" />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, shallowRef, onMounted, onUnmounted, watch, computed } from 'vue';
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DataZoomComponent,
  LegendComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';

// 注册必要的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DataZoomComponent,
  LegendComponent,
  LineChart,
  CanvasRenderer
]);

const props = defineProps({
  seasonalityData: {
    type: Array,
    default: () => []
  },
  loading: {
    type: Boolean,
    default: false
  }
});

const chartRef = ref(null);
const chart = shallowRef(null);
let resizeObserver = null;

// 动态生成图例
const legendItems = computed(() => {
  const years = props.seasonalityData.map(item => ({
    year: item.year, 
    isPrediction: item.is_prediction
  }));
  
  const colors = ['#3a36db', '#00c9ff', '#00e1d9', '#00ffb3'];
  
  return years.map((year, index) => ({
    text: `${year.year}年${year.isPrediction ? ' (预测)' : ''}`,
    color: colors[index % colors.length]
  }));
});

// 监听数据变化，更新图表
watch(() => props.seasonalityData, (newData) => {
  if (chart.value && newData?.length > 0) {
    updateChart();
  }
}, { deep: true });

// 监听加载状态
watch(() => props.loading, (newVal) => {
  if (!newVal && chart.value) {
    updateChart();
  }
});

onMounted(() => {
  if (chartRef.value) {
    initChart();
    
    // 监听窗口大小变化，添加节流函数以避免频繁触发
    const resizeHandler = () => {
      if (chart.value) {
        chart.value.resize();
      }
    };
    
    // 使用防抖函数处理resize事件
    const debouncedResize = debounce(resizeHandler, 100);
    
    resizeObserver = new ResizeObserver(() => {
      debouncedResize();
    });
    resizeObserver.observe(chartRef.value);
  }
});

onUnmounted(() => {
  // 销毁图表实例
  if (chart.value) {
    chart.value.dispose();
    chart.value = null;
  }
  
  // 清除resize观察者
  if (resizeObserver) {
    resizeObserver.disconnect();
    resizeObserver = null;
  }
});

// 初始化图表
function initChart() {
  if (!chartRef.value) return;
  
  // 确保图表容器有固定高度
  const container = chartRef.value;
  if (!container.style.height || container.style.height === 'auto') {
    container.style.height = '400px';
  }
  
  chart.value = echarts.init(chartRef.value);
  updateChart();
}

// 更新图表数据
function updateChart() {
  if (!chart.value || props.loading) return;
  
  // 准备数据
  const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
  const series = [];
  
  // 线条颜色
  const colors = ['#3a36db', '#00c9ff', '#00e1d9', '#00ffb3'];
  
  // 为每年创建一条折线
  props.seasonalityData.forEach((yearData, index) => {
    const color = colors[index % colors.length];
    const isPrediction = yearData.is_prediction || false;
    
    series.push({
      name: `${yearData.year}年${isPrediction ? ' (预测)' : ''}`,
      type: 'line',
      data: yearData.data.map(item => item.amount),
      smooth: true,
      symbol: 'circle',
      symbolSize: isPrediction ? 8 : 6,
      lineStyle: {
        width: isPrediction ? 4 : 3,
        type: isPrediction ? 'dashed' : 'solid',
        color: color
      },
      itemStyle: {
        color: color,
        borderColor: '#fff',
        borderWidth: 2
      }
    });
  });
  
  // 设置图表选项
  const option = {
    backgroundColor: 'transparent',
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(19, 20, 42, 0.9)',
      borderColor: 'rgba(42, 42, 87, 0.8)',
      textStyle: {
        color: '#e0e0ff'
      },
      formatter: function(params) {
        const month = monthNames[params[0].dataIndex];
        let content = `<div style="padding: 5px"><div style="font-weight: bold; margin-bottom: 8px">${month}</div>`;
        
        params.forEach(param => {
          let isPrediction = param.seriesName.includes('预测');
          let color = param.color;
          let value = param.value.toLocaleString('zh-CN', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2
          });
          
          content += `
            <div style="display: flex; align-items: center; margin-bottom: 5px">
              <span style="display: inline-block; width: 10px; height: 10px; background-color: ${color}; margin-right: 5px; border-radius: 50%"></span>
              <span>${param.seriesName}: </span>
              <span style="margin-left: 5px; font-weight: 600">¥${value}</span>
              ${isPrediction ? '<span style="margin-left: 5px; font-size: 12px; color: #00ffb3">预测</span>' : ''}
            </div>
          `;
        });
        
        content += '</div>';
        return content;
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '10%',
      top: '10%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: monthNames,
      axisLine: {
        lineStyle: {
          color: 'rgba(113, 113, 166, 0.3)'
        }
      },
      axisLabel: {
        color: '#7171a6'
      },
      axisTick: {
        alignWithLabel: true,
        lineStyle: {
          color: 'rgba(113, 113, 166, 0.3)'
        }
      }
    },
    yAxis: {
      type: 'value',
      axisLine: {
        show: false
      },
      axisLabel: {
        color: '#7171a6',
        formatter: function(value) {
          if (value >= 1000000) {
            return (value / 1000000).toFixed(1) + 'M';
          } else if (value >= 1000) {
            return (value / 1000).toFixed(0) + 'K';
          }
          return value;
        }
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(113, 113, 166, 0.1)'
        }
      }
    },
    series: series
  };
  
  chart.value.setOption(option, true);
}

// 防抖函数
function debounce(fn, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(context, args);
    }, delay);
  };
}
</script>

<style scoped>
.chart-container {
  background-color: var(--bg-card, #13142a);
  border-radius: 8px;
  border: 1px solid var(--border-color, #2a2a57);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
  overflow: hidden;
  height: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-color, #2a2a57);
  flex-wrap: wrap;
  gap: 10px;
}

.chart-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary, #e0e0ff);
}

.legend-container {
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
}

.legend-item {
  display: flex;
  align-items: center;
}

.legend-color {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-right: 5px;
}

.legend-text {
  font-size: 12px;
  color: var(--text-secondary, #b8b8cc);
}

.chart-content {
  flex: 1;
  position: relative;
  min-height: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.chart-content.is-loading {
  opacity: 0.7;
}

.echarts-wrapper {
  width: 100%;
  flex: 1;
  min-height: 0;
  height: 100%;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(19, 20, 42, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
  padding: 20px;
}
</style> 